8. 循环语句

在程序中经常会出现需要重复执行某一些代码的情况,比如我们计算1-100之间的数字的和,其实相当于把1开始的100个数字重复加到和上面去, 这个过程就是典型的重复执行过程,这种重复,我们叫做循环。

循环也需要语句支持,Python中循环分为两种(其实机会所有语言都这样):

  • for循环

  • while循环

这里面重复下,很多小白喜欢瞎想究竟学习哪种语言,或者想哪种语言好一些,我非常不推荐这样,毕竟我们不是学语言比较学的, 所有计算机语言严格上讲都是指令集,而这个真不是拍脑袋随便创造的,背后有完整的知识体系,比如编译原理,所以可以说, 所有计算机语言逻辑都是一致的,这也造成其实每种语言的大致组成部分都大差不差

8.1. for循环

for循环适合那种有固定重复次数的循环,比如我们上面的例子,计算 1-100 之间所有数字的和,这里其实有明确的循环次数,只有100个数字, 我们需要精准执行100次计算才行。

for循环的语句格式如下所示:

    for 变量 in 序列:
        语句1
        语句2
        ...

以上for循环的指令格式表示的意思是:

  1. 对于后面指定的序列里面的每一个值

  2. 我们把这个值暂时存放大气变量中

  3. 然后执行下面的语句1, 语句2 … …

  4. 重复这样的步骤直到每一个值都遍历一次

列表就是一列数字或者其他值,一般用中括号表示 例如 [‘zhangsan’, ‘lisi’, ‘wangwu’, 999]

8.2. 举个栗子吧

请看下面的案例:

# 列表就是一列数字或者其他值,一般用中括号表示
# 例如  ['zhangsan', 'lisi', 'wangwu','jingjing']

# 打印学生列表姓名
for name in  ['zhangsan', 'lisi', 'wangwu','jingjing']:
    print(name)

上面的代码机器简单,就是一个简单的遍历循环,需要注意的是中括号表示一共列表,我们后面会重点讲述列表的内容,这里暂时理解成 一队有顺序的数据, 运行结果如下所示:

zhangsan
lisi
wangwu
jingjing

我们啰嗦下上面案例的执行过程:

  1. 对于一列字符串组成的列表,需要依次执行

  2. 首先把列表中某个(其实是按顺序运行的)值赋值给变量name

  3. 执行for的语句循环体,即打印出这个变量的值

  4. 依次执行,直到把列表中所有的值都遍历一遍

循环体是否执行,如何执行跟变量 name其实没任何关系,循环体中也完全可以不出现name相关任何操作

一个说明性的案例如下:

# 本案例中变量跟循环体没任何关系,循环体也没出现变量
# 打印三遍北京图灵学院的校训
for i in [1,2,3]:
    print("我爱王晓静")

# 结果会打印出三遍 '我爱王晓静'
# 但for循环后面出现的打印语句,跟变量没任何关系
# 这里for的作用就只是负责让下面代码执行三遍而已

8.3. 一个正经的栗子

上面案例过于简单,下面的例子是,我们对列表里的人挨个进行检查,知道我们喜欢的静静出现为止:

# 打印学生列表姓名
# 如果是jingjign,那肯定是我的最爱呀,
# 如果是别的学生,那要冷酷的拒绝他
for name in  ['zhangsan', 'lisi', 'wangwu','jingjing']:
    print(name)
    if name == "jingjing":
        print("我的最爱{0}出现了".format(name))
    else:
        print("同学我们不约,不约,同学请自重")

在循环体重,我们加入了一个判断语句,只有当我们喜欢的静静出现了才执行else语句,其余的人我们只好残忍的拒绝:

zhangsan
同学我们不约,不约,同学请自重
lisi
同学我们不约,不约,同学请自重
wangwu
同学我们不约,不约,同学请自重
jingjing
我的最爱jingjing出现了

8.4. range介绍

我们经常会需要一队数字,这队数字从0或者1开始,然后按顺序递增,Python为我们准备了这样一个功能,可以让我们方便的生成一队数字,这些数字 按照一定的规律变化,这就是 range 函数。

下面解释并不精准,为了理解方便,我先这么说,后面会具体讲到range使用的技术点。

range函数中,首要功能是是生成一列数字,这列数字有始有终,在使用中,我们需要指定数字的开头和结尾,请看下面栗子:

# range练习
# 打印从1-10的数字
# 注意,一般在python中,如果由表示数字范围的两个数,一般是包含左边数字不包含右边数字
# randint是特例,他左右都包含
# range函数在python2 和 python3中有严重区别
for i in range(1,11):
    print(i) 

案例中,我们用range生成了一列数字,这列数字是由括号内两个数字表示,第一个数字表示这列数字从1开始,第二个数字11表示到11截止,并不 包括11, 每次增加1(即步长), 这样就会为我们生成需要的数字,请看运行结果:

1
2
3
4
5
6
7
8
9
10

如果需要,range还可以生成步长不为1的数列,比如我们需要1-100内的所有能被7整除的数字,可以这样行:

for i in range(7,100, 7):
    print(i)

上面的代码range函数中第一个和第二个数字的作用我们已经给大家介绍过了,第三个数字的作用是告诉系统,生成的数字队列每次增加7,即步长为7

8.5. for-else语句

以上是for语句的简单介绍,除了正常的逻辑之外,我们经常会有一种需求,即我们按照一定次数进行循环,当循环结束后,我们还希望能进行另外一个 单独的操作,你可以把它当成一个收尾工作,比如我让你跑操场10圈,跑完后去冲澡,此处冲澡就是一个收尾工作,且跟你跑多少圈没关系,只在最后执行一次。

在Python中,我们用for-else语句来实现这种功能,这里必须说明的是,else语句其实是一种可选语句,你可以看做世界上本来没有for循环,所谓的 for语句只是for-else语句的一个特例。

请看下面的例子:

    # for-else语句
    # 打印列表中的同学,
    # 如果没有在列表中,或者列表结束了,我们需要打印提示语句,表示不在爱了

    # 打印学生列表姓名
    # 如果是jingjign,那肯定是我的最爱呀,
    # 如果是别的学生,那要冷酷的拒绝他
    for name in  ['zhangsan', 'lisi', 'wangwu','jingjing']:
        print(name)
        if name == "jingjing":
            print("我的最爱{0}出现了".format(name))
        else:
            print("同学我们不约,不约,同学请自重")
    else:
        print("别的都不是我的学生,不会在爱了")
        print("别的都不是我的学生,不会在爱了")
        print("别的都不是我的学生,不会在爱了")

上面代码,正常循环完毕后还以后一个else语句,这个语句一共由三句话,即三个打印语句。

执行结果如下:

zhangsan
同学我们不约,不约,同学请自重
lisi
同学我们不约,不约,同学请自重
wangwu
同学我们不约,不约,同学请自重
jingjing
我的最爱jingjing出现了
别的都不是我的学生,不会在爱了
别的都不是我的学生,不会在爱了
别的都不是我的学生,不会在爱了

8.6. 循环之break,contineu,pass

除了正经的循环语句,我们可能还需要有一些特殊的需求,比如循环到一半不想继续了,或者跳过本次循环直接进入下一轮等,我们使用下面三个关键字实现:

  • break: 无条件结束整个循环,简称循环猝死

  • continue:无条件结束本次循环,从新进入下一轮循环

  • pass:表示略过,通常用于占位,也可以用在函数或者类里面,因为根据语法,某个地方必须有代码才可以,但我们暂时可能不确定具体内容,就用pass占位

break, continue语句对所有循环都有效,包括后面学习的while循环。

炒个栗子吧:

# 在数字1-10中,寻找数字7,一旦找到,打印出来,其余则什么都不做
# for 循环中的变量表示,一般用i,k,m,n,或者indx,idx,item之类
# 在python中,如果循环变量名称不重要,可以用下划线(_)代替

for i in range(1,11):
    if i == 7:
        print("我找到了")
        # 此出break表示结束整个for循环
        break
    else:
        continue
    
    # 注意,此处print永远不会被执行,思考为什么?
    print(i)

再炒个栗子:

# continue语句联系
# 在数字1-10中,寻找所有偶数,找到偶数后打印偶数

for i in range(1,11):
    if i % 2 == 1:
        # 不是偶数就啥也不干,这里的continue有点多余,可以用另外更简洁的形式
        # 此处纯属练习
        continue
        # 打印语句不会被执行
        print(i)
    else:
        print("{0} 是偶数".format(i))

运行结果是:

2 是偶数
4 是偶数
6 是偶数
8 是偶数
10 是偶数
# continue语句 版本 2
# 在数字1-10中,寻找所有偶数,找到偶数后打印偶数

for i in range(1,11):
    if i % 2 == 0:
        print("{0} 是偶数".format(i))
    
2 是偶数
4 是偶数
6 是偶数
8 是偶数
10 是偶数

一个比上面简洁点的🌰 :

# continue语句 版本 2
# 在数字1-10中,寻找所有偶数,找到偶数后打印偶数
# 本案例完整显示continue的用法和作用
for i in range(1,11):
    if i % 2 == 1:
        continue
        
    print("{0} 是偶数".format(i))

运行结果跟上面一致:

2 是偶数
4 是偶数
6 是偶数
8 是偶数
10 是偶数

一个pass的🌰:

# pass例子,一般用于占位
# pass没有跳过功能

for i in range(1,11):
    pass
    print("wo zai zheli")

运行结果是下面这样的,结果清楚的表明pass语句没有跳过功能:

wo zai zheli
wo zai zheli
wo zai zheli
wo zai zheli
wo zai zheli
wo zai zheli
wo zai zheli
wo zai zheli
wo zai zheli
wo zai zheli